﻿using ContactSMS.Commons.Responses;
using ContactSMS.Commons.Util;
using ContactSMS.Domain;
using ContactSMS.Domain.Dto;
using ContactSMS.Domain.Entity;
using ContactSMS.WebAPI.Common;
using ContactSMS.WebAPI.Controllers.Request;
using ContactSMS.WebAPI.Controllers.Responses;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace ContactSMS.WebAPI.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        private readonly ILoginRepository _loginRepository;
        private readonly IUserRepository _userRepository;
        private readonly IConfiguration _configuration;
        private readonly TokenService _tokenService;

        public LoginController(ILoginRepository loginRepository, IUserRepository userRepository, IConfiguration configuration, TokenService tokenService)
        {
            this._loginRepository = loginRepository;
            this._userRepository = userRepository;
            this._configuration = configuration;
            this._tokenService = tokenService;
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="addUserRequest"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Register([FromBody] AddUserRequest addUserRequest)
        {
            ServiceResponse<UserDto> resp = new ServiceResponse<UserDto>();

            if (string.IsNullOrEmpty(addUserRequest.UserName) ||
                string.IsNullOrEmpty(addUserRequest.PassWord) ||
                string.IsNullOrEmpty(addUserRequest.PassWordTwo) ||
                string.IsNullOrEmpty(addUserRequest.Phone) ||
                string.IsNullOrEmpty(addUserRequest.Email))
            {
                resp.Success = false;
                resp.Message = "用户名或密码或手机或邮箱不能为空";
                return Ok(resp);
            }

            if (!string.Equals(addUserRequest.PassWord, addUserRequest.PassWordTwo))
            {
                resp.Success = false;
                resp.Message = "两次密码不一样";
                return Ok(resp);
            }

            var existingUser = await this._userRepository.GetUserByUserNameAsync(addUserRequest.UserName);
            if (existingUser != null)
            {
                resp.Success = false;
                resp.Message = "用户名已存在";
                return Ok(resp);
            }

            var DomainModel = new User(addUserRequest.UserName, addUserRequest.PassWord, addUserRequest.Avatar, addUserRequest.Email, addUserRequest.Phone);
            await this._loginRepository.RegisterAsync(DomainModel);
            var userDto = new UserDto
            {
                Id = DomainModel.Id,
                UserName = DomainModel.UserName,
                Avatar = DomainModel.Avatar,
                CreatTime = DomainModel.CreatTime,
                UpdateTime = DomainModel.UpdateTime
            };
            resp.Success = true;
            resp.Message = "获取成功";
            resp.Data = userDto;
            return Ok(resp);
        }

        [HttpPost]
        public async Task<IActionResult> Login([FromBody] LoginRequest loginRequest)
        {
            ServiceResponse<TokenResponse> resp = new ServiceResponse<TokenResponse>();
            if (string.IsNullOrEmpty(loginRequest.UserName) ||
                string.IsNullOrEmpty(loginRequest.PassWord))
            {
                resp.Success = false;
                resp.Message = "用户名或密码不能为空";
                return BadRequest(resp);
            }

            var existingUser = await this._userRepository.GetUserByUserNameAsync(loginRequest.UserName);
            if (existingUser == null)
            {
                resp.Success = false;
                resp.Message = "用户或密码错误";
                return BadRequest(resp);
            }
            bool isVerify = PassWordUtil.VerifyPassword(existingUser.PassWord, loginRequest.PassWord);
            if (!isVerify)
            {
                resp.Success = false;
                resp.Message = "密码错误";
                return BadRequest(resp);
            }
            //string token = CreateToken(existingUser);
            string Id = existingUser.Id.ToString();
            List<Claim> claims = new List<Claim> {
                new Claim(ClaimTypes.NameIdentifier, Id),
                new Claim(ClaimTypes.Name, existingUser.UserName),
            };
            string accessToken = this._tokenService.GenerateAccessToken(claims);
            var refreshToken = _tokenService.GenerateRefreshToken(existingUser.UserName);
            var tokenResponse = new TokenResponse()
            {
                AccessToken = accessToken,
                RefreshToken = refreshToken
            };
            resp.Success = true;
            resp.Message = "获取成功";
            resp.Data = tokenResponse;
            return Ok(resp);
        }

        private string CreateToken(User user)
        {
            List<Claim> claims = new List<Claim> {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                _configuration.GetSection("TokenSettings:Token").Value!));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

            var token = new JwtSecurityToken(
                    claims: claims,
                    expires: DateTime.Now.AddDays(1),
                    signingCredentials: creds
                );

            var jwt = new JwtSecurityTokenHandler().WriteToken(token);

            return jwt;
        }
    }
}
